package com.bird.system.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.RandomUtil;
import com.bird.common.utils.StringUtil;
import com.bird.system.domain.entity.SysCodeRuleEntity;
import com.bird.system.domain.params.SysCodeRuleQueryParam;
import com.bird.system.domain.params.SysCodeRuleUpdateParam;
import com.bird.system.domain.vo.SysCodeRuleListPcVO;
import com.bird.system.enums.BaseEnum;
import com.bird.system.enums.CodeRuleTypeEnum;
import com.bird.system.mapper.SysCodeRuleMapper;
import com.bird.system.service.ISysCodeRuleService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 系统编码规则配置Service业务层处理
 *
 * @author bird
 * @date 2020-07-22
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysCodeRuleServiceImpl extends IBaseServiceImpl<SysCodeRuleEntity, SysCodeRuleMapper> implements ISysCodeRuleService {

	/**
	 * 查询系统编码规则配置列表
	 *
	 * @param queryParam 系统编码规则配置 查询参数
	 * @return 系统编码规则配置
	 */
	@Override
	public List<SysCodeRuleListPcVO> selectListPC(SysCodeRuleQueryParam queryParam) {
		List<SysCodeRuleListPcVO> sysCodeRules = mapper.selectListPC(queryParam);
		return sysCodeRules;
	}

	/**
	 * 新增系统编码规则配置
	 *
	 * @param updateParam 系统编码规则配置 新增参数
	 * @return 结果
	 */
	@Override
	public Long insertPC(SysCodeRuleUpdateParam updateParam, Long loginId) {
		SysCodeRuleEntity entity = updateParam.covert();
		entity.setCreater(loginId);
		this.insert(entity);
		return entity.getId();
	}

	/**
	 * 修改系统编码规则配置
	 *
	 * @param updateParam 系统编码规则配置 修改参数
	 * @return 结果
	 */
	@Override
	public int updateByIdPC(SysCodeRuleUpdateParam updateParam) {
		SysCodeRuleEntity entity = updateParam.covert();
		int result = this.updateById(entity);
		return result;
	}

	@Override
	public String buildCode(String ruleCode) {
		String code = null;
		SysCodeRuleEntity sysCodeRuleEntity = this.selectOne(Select().forUpdate().where().andEqualTo(SysCodeRuleEntity::getRuleCode, ruleCode).end());
		if (sysCodeRuleEntity == null) {
			// 不存在
			return code;
		}
		// 判断规则
		CodeRuleTypeEnum codeRuleTypeEnum = (CodeRuleTypeEnum) BaseEnum.valueOfEnum(CodeRuleTypeEnum.class, sysCodeRuleEntity.getFormatType());
		switch (codeRuleTypeEnum) {
			case TIME_RANDOM:
				code = this.timeRandom(sysCodeRuleEntity);
				break;
			case SERIAL:
				code = this.serial(sysCodeRuleEntity);
				break;
			case TIME_SERIAL:
				code = this.timeSerial(sysCodeRuleEntity);
				break;
		}
		this.updateById(sysCodeRuleEntity);
		return code;
	}

	/**
	 * 时间加序列方式
	 *
	 * @param sysCodeRuleEntity
	 * @return
	 */
	private String timeSerial(SysCodeRuleEntity sysCodeRuleEntity) {
		StringBuilder code = new StringBuilder();
		SimpleDateFormat sdf = new SimpleDateFormat(sysCodeRuleEntity.getFormatStr());
		String curMonth = sdf.format(new Date());
		if (!curMonth.equals(sysCodeRuleEntity.getCurFormatVal())) {
			// 当前值不相等，重置从1开始
			sysCodeRuleEntity.setSerial(1);
		}
		sysCodeRuleEntity.setCurFormatVal(curMonth);
		if (StringUtil.isNotBlank(sysCodeRuleEntity.getRulePrefix())) {
			code.append(sysCodeRuleEntity.getRulePrefix());
		}
		code.append(sysCodeRuleEntity.getCurFormatVal());
		String num = String.format("%0" + sysCodeRuleEntity.getSerialLen() + "d", sysCodeRuleEntity.getSerial());
		code.append(num);
		// 序号+1
		sysCodeRuleEntity.setSerial(sysCodeRuleEntity.getSerial() + 1);
		return code.toString();
	}

	/**
	 * 只是序列
	 *
	 * @param sysCodeRuleEntity
	 * @return
	 */
	private String serial(SysCodeRuleEntity sysCodeRuleEntity) {
		StringBuilder code = new StringBuilder();
		if (StringUtil.isNotBlank(sysCodeRuleEntity.getRulePrefix())) {
			code.append(sysCodeRuleEntity.getRulePrefix());
		}
		String num = String.format("%0" + sysCodeRuleEntity.getSerialLen() + "d", sysCodeRuleEntity.getSerial());
		code.append(num);
		// 序号+1
		sysCodeRuleEntity.setSerial(sysCodeRuleEntity.getSerial() + 1);
		return code.toString();
	}

	/**
	 * 日期加随机数
	 *
	 * @param sysCodeRuleEntity
	 * @return
	 */
	private String timeRandom(SysCodeRuleEntity sysCodeRuleEntity) {
		StringBuilder code = new StringBuilder();
		SimpleDateFormat sdf = new SimpleDateFormat(sysCodeRuleEntity.getFormatStr());
		String curMonth = sdf.format(new Date());
		sysCodeRuleEntity.setCurFormatVal(curMonth);
		if (StringUtil.isNotBlank(sysCodeRuleEntity.getRulePrefix())) {
			code.append(sysCodeRuleEntity.getRulePrefix());
		}
		code.append(sysCodeRuleEntity.getCurFormatVal());
		// 获取当前时间的秒+毫秒
		String num = "";
		DateTime now = DateTime.now();
		int diff = sysCodeRuleEntity.getSerialLen() - 5;
		int second = now.getField(DateField.SECOND);
		int millisecond = now.getField(DateField.MILLISECOND);
		if (diff > 0) {
			num += RandomUtil.randomNumbers(diff);
		}
		code.append(num + second + millisecond);
		return code.toString();
	}

}
